#ifndef MYSQL_CONNECTION_POOL_H
#define MYSQL_CONNECTION_POOL_H

#include <mysql/mysql.h>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string>
#include <memory>
#include <stdexcept>
#include <atomic>
#include <iostream>

class MySQLConnectionPool {
public:
    
    // 单例模式获取连接池实例
    static MySQLConnectionPool& getInstance() {
        static MySQLConnectionPool instance;
        return instance;
    }

    // 禁止拷贝和赋值
    MySQLConnectionPool(const MySQLConnectionPool&) = delete;
    MySQLConnectionPool& operator=(const MySQLConnectionPool&) = delete;

    // 初始化连接池
    bool init(const std::string& host, const std::string& user,
              const std::string& password, const std::string& dbName,
              unsigned int port = 3306, unsigned int minSize = 5,
              unsigned int maxSize = 20, unsigned int timeout = 3000) {
        std::lock_guard<std::mutex> lock(m_mutex);
        
        // 检查是否已初始化
        if (m_initialized) {
            return true;
        }
        
        // 保存配置
        m_host = host;
        m_user = user;
        m_password = password;
        m_dbName = dbName;
        m_port = port;
        m_minSize = minSize;
        m_maxSize = maxSize;
        m_timeout = timeout;
        
        // 创建初始连接
        for (unsigned int i = 0; i < minSize; ++i) {
            MYSQL* conn = createConnection();
            if (conn) {
                m_connections.push(conn);
                ++m_currentSize;
            }
        }
        
        if (m_connections.size() > 0) {
            m_initialized = true;
            return true;
        }
        
        return false;
    }

    // 获取连接
    std::shared_ptr<MYSQL> getConnection() {
        std::unique_lock<std::mutex> lock(m_mutex);
        // std::cout<<"ready for getConnect"<<std::endl;
        // 等待可用连接或创建新连接
        if (m_connections.empty() && m_currentSize < m_maxSize) {
            MYSQL* conn = createConnection();
            if (conn) {
                m_connections.push(conn);
                ++m_currentSize;
            }
        }
        // 等待可用连接
        if (m_connections.empty()) {
            if (!m_cv.wait_for(lock, std::chrono::milliseconds(m_timeout),
                              [this] { std::cout<<"empty in"<<std::endl;return !m_connections.empty(); })) {
                throw std::runtime_error("获取连接超时");
            }
        }
        
        // 获取连接并封装为智能指针
        MYSQL* conn = m_connections.front();
        m_connections.pop();
        
        // 使用自定义删除器的智能指针
        return std::shared_ptr<MYSQL>(conn, [this](MYSQL* conn) {
            if (conn) {
                std::lock_guard<std::mutex> lock(m_mutex);

                if(mysql_reset_connection(conn)!=0)
                {
                    std::cerr<<"连接重置失败："<<mysql_error(conn)<< std::endl;
                    mysql_close(conn);//重置失败则直接关闭连接
                    return;
                }
                m_connections.push(conn);
                m_cv.notify_one();
            }
        });
    }

    // 获取当前连接数
    unsigned int getCurrentSize() const {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_currentSize;
    }

    // 销毁连接池
    ~MySQLConnectionPool() {
        destroy();
    }

    // 手动销毁连接池
    void destroy() {
        std::lock_guard<std::mutex> lock(m_mutex);
        
        if (!m_initialized) {
            return;
        }
        
        // 关闭所有连接
        while (!m_connections.empty()) {
            MYSQL* conn = m_connections.front();
            m_connections.pop();
            mysql_close(conn);
        }
        
        m_currentSize = 0;
        m_initialized = false;
    }

private:
    // 私有构造函数
    MySQLConnectionPool() = default;

    // 创建新连接
    MYSQL* createConnection() {
        MYSQL* conn = mysql_init(nullptr);
        if (!conn) {
            return nullptr;
        }

        if (!mysql_real_connect(conn, m_host.c_str(), m_user.c_str(),
                               m_password.c_str(), m_dbName.c_str(),
                               m_port, nullptr, 0)) {
            std::cerr << "mysql_real_connect failed: " << mysql_error(conn) << std::endl;
            mysql_close(conn);
            return nullptr;
        }
        
        // 设置字符集
        if (mysql_set_character_set(conn, "utf8mb4")) {
            std::cerr << "mysql_set_character_set failed: " << mysql_error(conn) << std::endl;
            mysql_close(conn);
            return nullptr;
        }

        return conn;
    }

private:
    // 配置参数
    std::string m_host;
    std::string m_user;
    std::string m_password;
    std::string m_dbName;
    unsigned int m_port;
    unsigned int m_minSize;    // 最小连接数
    unsigned int m_maxSize;    // 最大连接数
    unsigned int m_timeout;    // 获取连接超时时间(毫秒)
    
    // 连接池状态
    std::queue<MYSQL*> m_connections;  // 连接队列
    unsigned int m_currentSize = 0;    // 当前连接数
    bool m_initialized = false;        // 是否已初始化
    
    // 线程安全控制
    mutable std::mutex m_mutex;
    std::condition_variable m_cv;
};

#endif